/*

    tools23d - tools for converting images to 3D formats.
    Copyright (C) 2014  Dave Gorst

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

/**
 * @file   photo23d.c
 * @brief  Main entry point to photo23d code called from main().
 *
 */

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#include "FreeImage.h"

#include "tools23d.h"
#include "photo23d.h"
#include "frameset.h"
#include "cli-common.h"
#include "cli-photo.h"
#include "glob-all.h"
#include "image-fi.h"
#include "image.h"
#include "util.h"

/**
@brief  Main photo23d function.

Main photo23d function, called from main ().

Syntax :

photo23d -l \<left input file patter\n> -r \<right input file pattern\> -o \<output directory/filename\> [options]

@return Return ::t3d_return code indicating status.
*/

t3d_return T3D_Run (params * cli_params)
{
	image_details target_details, first_frame_details;

	unsigned int frame;
	unsigned int number_of_left_frames;
	unsigned int number_of_right_frames;
	unsigned int left_globule;
	unsigned int right_globule;

	file_entry * left_eye_file;
	file_entry * right_eye_file;

	char * left_eye_filename;
	char * right_eye_filename;

	time_t change_time;

	char * write_filename;

	BOOL success = TRUE;

	int current_left_input_filename = cli_params->number_of_left_filenames;
	int current_right_input_filename = cli_params->number_of_right_filenames;

	if (cli_params->output_filename == NULL)
	{
		T3D_SetLastError ("Missing output file pattern.");
		return t3d_bad_parameter;
	}

	if ((!cli_params->number_of_left_filenames) || (!cli_params->number_of_right_filenames))
	{
		T3D_SetLastError ("Missing input files.");
		return t3d_bad_parameter;
	}

    T3D_InitialiseBackend ();

	left_globule = T3D_InitialiseGlob ();
	right_globule = T3D_InitialiseGlob ();

	while (current_left_input_filename)
		T3D_PopulateGlob (left_globule, cli_params->left_filenames [--current_left_input_filename]);

	while (current_right_input_filename)
		T3D_PopulateGlob (right_globule, cli_params->right_filenames [--current_right_input_filename]);

	number_of_left_frames = T3D_GetNumberOfEntries (left_globule);
	number_of_right_frames = T3D_GetNumberOfEntries (right_globule);

	if (number_of_left_frames != number_of_right_frames)
	{
		T3D_SetLastError ("Left and right eyes have a differing number of input frames (%d versus %d).", number_of_left_frames, number_of_right_frames);
		return t3d_bad_parameter;
	}

	if (number_of_left_frames)
	{

		T3D_SortGlobule(left_globule, cli_params->sorttype);
		T3D_SortGlobule(right_globule, cli_params->sorttype);

		T3D_RetrievePictureDetails (T3D_RetrieveGlobEntry (left_globule, 0)->filepath, &first_frame_details.format, &first_frame_details.width, &first_frame_details.height, &first_frame_details.depth);

		if ((!cli_params->width) || (!cli_params->height))
		{
			target_details.width = first_frame_details.width;
			target_details.height = first_frame_details.height;
		}
		else
		{
			target_details.width = cli_params->width;
			target_details.height = cli_params->height;

		}
		target_details.depth = first_frame_details.depth;

		if (!T3D_InitialiseImageHandling(&target_details, cli_params->filter, cli_params->loglevel))
		{
			T3D_SetLastError("Couldn't initialise image library.");
			return t3d_bad_parameter;
		}

		target_details.format = T3D_RetrievePictureType (cli_params->output_filename);

		if (target_details.format == IMAGE_FORMAT_UNKNOWN)
		{
			/* TODO - test. */
			if (!T3D_RaiseWarning (&cli_params->always_yes, "WARNING : Output image format could not be determined. Using input type."))
				return t3d_bad_parameter;
			target_details.format = first_frame_details.format;
		}

		for (frame = 0; ((frame < number_of_left_frames) && (success)); frame ++)
		{
			left_eye_file = T3D_RetrieveGlobEntry (left_globule, frame);
			right_eye_file = T3D_RetrieveGlobEntry (right_globule, frame);

			change_time = left_eye_file->change_time;

			if ((success = ((write_filename = T3D_ProcessWriteFilename(cli_params->output_filename, frame, change_time)) != NULL)))
			{

				left_eye_filename = left_eye_file->filepath;
				right_eye_filename = right_eye_file->filepath;

				success = T3D_Write3DImage
				(
					left_eye_filename,
					right_eye_filename,
					write_filename,
					&target_details,
					cli_params->mode,
					cli_params->filter,
					cli_params->croptype,
					cli_params->preserve_aspect_ratio,
					cli_params->loglevel,
					cli_params->zoom
				);

				/* TODO - output error message set by FreeImage if failed */
			}
			else
			{
				T3D_SetLastError ("Malformed file time or format specifier when trying to create output filename.");
				return t3d_bad_parameter;
			}
		}

	}
	else
	{
		T3D_SetLastError ("Nothing to do!");
		return t3d_bad_parameter;
	}

	T3D_ShutdownImageHandling();

	T3D_ShutdownGlob ();

	T3D_ShutdownBackend ();

	return t3d_success;
}

